#include "xsRendPCH.hpp"

#include <windows.h>

extern xs::Event g_event; // :(
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

//=================================================================================================
// CenterWindow
//=========

void CenterWindow( HWND hwnd )
{
    RECT rc ;
    
    GetWindowRect ( hwnd, &rc ) ;
    
    SetWindowPos( hwnd, 0, 
        (GetSystemMetrics(SM_CXSCREEN) - rc.right)/2,
        (GetSystemMetrics(SM_CYSCREEN) - rc.bottom)/2,
         0, 0, SWP_NOZORDER|SWP_NOSIZE );
}


//=================================================================================================
// CreateWindow
//=========

void CreateWnd(HWND &hwnd, int width, int height, const wchar_t *caption, bool fullscreen)
{
	WNDCLASSEX wc;
	HINSTANCE hInstance = GetModuleHandle(0);

	ZeroMemory(&wc, sizeof(WNDCLASSEX));

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = (WNDPROC)WindowProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.lpszClassName = L"xsClass";
	wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(100));
	wc.hIconSm = wc.hIcon;

	RegisterClassEx(&wc);

	RECT wndrect;
	wndrect.left = 0;
	wndrect.right = width;
	wndrect.top = 0;
	wndrect.bottom = height;

	DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

	if(fullscreen)
	{
		style = WS_POPUP;
	}

	AdjustWindowRect(&wndrect,style,false);

	width = wndrect.right - wndrect.left;
	height = wndrect.bottom - wndrect.top;

	hwnd = CreateWindowEx(NULL,
		L"xsClass",		// name of the window class
		caption,			// title of the window
		style,			// window style
		0,				// x-position of the window
		0,				// y-position of the window
		width,			// width of the window
		height,			// height of the window
		NULL,				// we have no parent window, NULL
		NULL,				// we aren't using menus, NULL
		hInstance,		// application handle
		NULL);			// used with multiple windows, NULL

	//if(!fullscreen)
		CenterWindow(hwnd);
	ShowWindow(hwnd, SW_SHOW);
}

//=================================================================================================
// WindowProc
//=========

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	g_event.type = xs::EventTypes::UNKNOWN;

	switch(message)
	{
	case WM_DESTROY:
	case WM_CLOSE:
		{
			g_event.type = xs::EventTypes::QUIT;
			PostQuitMessage(0);
			return 0;
		} 
		break;
	case WM_CHAR:
		{	
			g_event.type = xs::EventTypes::KEYBOARD;
			g_event.keyboard.event = xs::KeyEvents::TYPE;
			g_event.keyboard.unicode = (wchar_t)wParam;
		}
		break;
	case WM_MOUSEMOVE:
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_RBUTTONDOWN:
	case WM_RBUTTONUP:
		{
			g_event.type = xs::EventTypes::MOUSE;

			if(message == WM_MOUSEMOVE)
				g_event.mouse.event = xs::MouseEvents::MOVE;
			else if(message == WM_LBUTTONDOWN)
				g_event.mouse.event = xs::MouseEvents::LMB_DOWN;
			else if(message == WM_LBUTTONUP)
				g_event.mouse.event = xs::MouseEvents::LMB_UP;
			else if(message == WM_RBUTTONDOWN)
				g_event.mouse.event = xs::MouseEvents::RMB_DOWN;
			else if(message == WM_RBUTTONUP)
				g_event.mouse.event = xs::MouseEvents::RMB_UP;

			g_event.mouse.x = (short)LOWORD(lParam);
			g_event.mouse.y = (short)HIWORD(lParam);
		} 
		break;

	case WM_KEYDOWN:
	case WM_KEYUP:
		{
			g_event.type = xs::EventTypes::KEYBOARD;
			g_event.keyboard.key = (int)wParam;

			g_event.keyboard.event = 
				(message == WM_KEYDOWN ? xs::KeyEvents::DOWN : xs::KeyEvents::UP);
		}
		break;
	default:
		break;
	}

	// Handle any messages the switch statement didn't
	return DefWindowProc (hWnd, message, wParam, lParam);
} 